/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef PERIPHERAL_SWITCH_CONTROL_H__
#define PERIPHERAL_SWITCH_CONTROL_H__

#include <string>
#include <mutex>
#include <vector>
#include "nlohmann/json.hpp"

namespace El {
namespace Peripheral {

/**
 * @brief 开关控制类（单例模式，配置驱动）
 * 监听配置变化并自动控制相应的开关硬件
 * 支持广播、警灯、备用1、备用2四个开关
 */
class SwitchControl {
public:
    /**
     * @brief 获取单例实例
     * @return SwitchControl& 单例实例引用
     */
    static SwitchControl &GetInstance();

    /**
     * @brief 启动开关控制服务
     * 注册配置监听器，开始监听配置变化
     * @return bool true=成功，false=失败
     */
    bool Start();

    /**
     * @brief 停止开关控制服务
     * 取消配置监听器注册
     * @return bool true=成功，false=失败
     */
    bool Stop();

    /**
     * @brief 获取广播开关状态
     * @return bool true=开启，false=关闭
     */
    bool GetBroadcastState() const { return broadcastEnabled_; }

    /**
     * @brief 获取警灯开关状态
     * @return bool true=开启，false=关闭
     */
    bool GetWarningLightState() const { return warningLightEnabled_; }

    /**
     * @brief 获取备用1开关状态
     * @return bool true=开启，false=关闭
     */
    bool GetSpare1State() const { return spare1Enabled_; }

    /**
     * @brief 获取备用2开关状态
     * @return bool true=开启，false=关闭
     */
    bool GetSpare2State() const { return spare2Enabled_; }

private:
    SwitchControl();
    ~SwitchControl();

    // 禁止拷贝构造和赋值
    SwitchControl(const SwitchControl&) = delete;
    SwitchControl& operator=(const SwitchControl&) = delete;

    /**
     * @brief 广播配置变化回调
     * @param config 广播配置内容
     * @return bool true=处理成功，false=处理失败
     */
    bool OnBroadcastConfigChanged(const nlohmann::json &config);

    /**
     * @brief 警灯配置变化回调
     * @param config 警灯配置内容
     * @return bool true=处理成功，false=处理失败
     */
    bool OnWarningLightConfigChanged(const nlohmann::json &config);

    /**
     * @brief 备用1配置变化回调
     * @param config 备用1配置内容
     * @return bool true=处理成功，false=处理失败
     */
    bool OnSpare1ConfigChanged(const nlohmann::json &config);

    /**
     * @brief 备用2配置变化回调
     * @param config 备用2配置内容
     * @return bool true=处理成功，false=处理失败
     */
    bool OnSpare2ConfigChanged(const nlohmann::json &config);

    /**
     * @brief 发送串口控制命令
     * @param command 十六进制命令字符串
     * @return bool true=成功，false=失败
     */
    bool SendCommand(const std::string &command);

    /**
     * @brief 将十六进制字符串转换为字节数组
     * @param hexStr 十六进制字符串
     * @return std::vector<uint8_t> 字节数组
     */
    std::vector<uint8_t> HexStringToBytes(const std::string &hexStr);

private:
    mutable std::mutex mutex_;  // 线程安全保护
    bool initialized_;          // 初始化状态
    std::string uartName_;     // 使用的串口名称

    // 各开关状态
    bool broadcastEnabled_;
    bool warningLightEnabled_;
    bool spare1Enabled_;
    bool spare2Enabled_;

    // 配置监听器ID
    int32_t broadcastListenerId_;
    int32_t warningLightListenerId_;
    int32_t spare1ListenerId_;
    int32_t spare2ListenerId_;

    // 串口控制命令（十六进制字符串）
    static const std::string BROADCAST_ON_CMD;
    static const std::string BROADCAST_OFF_CMD;
    static const std::string WARNING_LIGHT_ON_CMD;
    static const std::string WARNING_LIGHT_OFF_CMD;
    static const std::string SPARE1_ON_CMD;
    static const std::string SPARE1_OFF_CMD;
    static const std::string SPARE2_ON_CMD;
    static const std::string SPARE2_OFF_CMD;
};

} // namespace Peripheral
} // namespace El

#endif // PERIPHERAL_SWITCH_CONTROL_H__